import { RouteRecordRaw } from "vue-router";
import { defineStore } from "pinia";
import { constantRoutes } from "@/router";
import { store } from "@/store";
import { listRoutes } from "@/api/menu";

const modules = import.meta.glob("../../views/**/**.vue");
const BasicLayout = () => import("@/layout/BasicLayout/index.vue");
const CourseLayout = () => import("@/layout/CourseLayout/index.vue");
const CorrectLayout = () => import("@/layout/CorrectLayout/index.vue");
const StudyLayout = () => import("@/layout/StudyLayout/index.vue");

/**
 * 过滤layout中的菜单合集
 * @param routes
 * @param layout
 * @returns
 */
const extractMenuItemsByLayout = (
  routes: RouteRecordRaw[],
  layout: string,
  route: RouteRecordRaw[]
) => {
  for (const item of routes) {
    if (item.meta?.layout === layout && !item.children) {
      const newItem = { ...item };
      if (layout === "CourseLayout") {
        newItem.path = "/courseinfo/" + newItem.path;
      } else if (layout === "CorrectLayout") {
        newItem.path = "/correctinfo/" + newItem.path;
      } else {
        newItem.path = "/studyinfo/" + newItem.path;
      }
      newItem.meta!.seleted = false;
      route.push(newItem);
    }

    if (item.children) {
      extractMenuItemsByLayout(item.children, layout, route);
    }
  }
};

/**
 * Use meta.role to determine if the current user has permission
 *
 * @param roles 用户角色集合
 * @param route 路由
 * @returns
 */
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
  if (route.meta && route.meta.roles) {
    // 角色【超级管理员】拥有所有权限，忽略校验
    /*  if (roles.includes("admin")) {
      return true;
    } */
    return roles.some((role) => {
      if (route.meta?.roles !== undefined) {
        return (route.meta.roles as string[]).includes(role);
      }
    });
  }
  return false;
};

/**
 * 递归过滤有权限的异步(动态)路由
 *
 * @param routes 接口返回的异步(动态)路由
 * @param roles 用户角色集合
 * @returns 返回用户有权限的异步(动态)路由
 */
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
  const asyncRoutes: RouteRecordRaw[] = [];
  routes.forEach((route) => {
    // ES6扩展运算符复制新对象
    const tmpRoute = { ...route };
    // 判断用户(角色)是否有该路由的访问权限
    if (hasPermission(roles, tmpRoute)) {
      if (tmpRoute.component?.toString() == "BasicLayout") {
        tmpRoute.component = BasicLayout;
      } else if (tmpRoute.component?.toString() == "CourseLayout") {
        tmpRoute.component = CourseLayout;
      } else if (tmpRoute.component?.toString() == "CorrectLayout") {
        tmpRoute.component = CorrectLayout;
        tmpRoute.name = "Correctinfo";
      } else if (tmpRoute.component?.toString() == "StudyLayout") {
        tmpRoute.component = StudyLayout;
        tmpRoute.name = "Studyinfo";
      } else {
        const component = modules[`../../views/${tmpRoute.component}.vue`];
        if (component) {
          tmpRoute.component = component;
        } else {
          tmpRoute.component = modules[`../../views/error-page/404.vue`];
        }
      }

      if (tmpRoute.children) {
        tmpRoute.children = filterAsyncRoutes(tmpRoute.children, roles);
      }
      asyncRoutes.push(tmpRoute);
    }
  });

  return asyncRoutes;
};

// setup
export const usePermissionStore = defineStore("permission", () => {
  // state
  const routes = ref<RouteRecordRaw[]>([]);
  const routes2 = ref<RouteRecordRaw[]>([]);
  const routes3 = ref<RouteRecordRaw[]>([]);
  const routes4 = ref<RouteRecordRaw[]>([]);
  // actions
  function setRoutes(newRoutes: RouteRecordRaw[]) {
    routes.value = constantRoutes.concat(newRoutes);

    routes2.value = [];
    routes3.value = [];
    routes4.value = [];
    extractMenuItemsByLayout(newRoutes, "CourseLayout", routes2.value);
    extractMenuItemsByLayout(newRoutes, "StudyLayout", routes3.value);
    extractMenuItemsByLayout(newRoutes, "CorrectLayout", routes4.value);
  }
  /**
   * 生成动态路由
   *
   * @param roles 用户角色集合
   * @returns
   */
  function generateRoutes(roles: string[]) {
    return new Promise<RouteRecordRaw[]>((resolve, reject) => {
      // 接口获取所有路由
      listRoutes()
        .then(({ data: asyncRoutes }) => {
          // 根据角色获取有访问权限的路由
          const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);

          setRoutes(accessedRoutes);
          resolve(accessedRoutes);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }
  return { routes, routes2, routes3, routes4, setRoutes, generateRoutes };
});

// 非setup
export function usePermissionStoreHook() {
  return usePermissionStore(store);
}
